// 12.1 参数化的声明
// 在C++模板编程中，参数化声明是一个核心概念，它允许我们创建可以适应不同类型和值的通用代码。以下是这一节的主要内容：

// 基本概念
// 参数化声明是指使用模板参数来定义类、函数、变量或其他实体的过程。这些参数可以是类型参数、非类型参数或模板模板参数。

// 类型参数
// 类型参数是最常见的模板参数形式，使用typename或class关键字声明：
template <typename T> // 或 template<class T>
class Container
{
    T element;
    // ...
};

// 非类型参数
// 非类型参数是具有特定类型的值，如整数、指针或引用：
template <typename T, int Size>
class Array
{
    T elements[Size];
    // ...
};
// 非类型参数的限制：
// -必须是编译时常量
// -可以是整型、枚举、指针、引用或nullptr_t
// -不能是浮点数、类对象或字符串字面量

// 模板模板参数
// 模板模板参数是接受模板作为参数的模板参数：
template <template <typename> class Container>
class Adapter
{
    Container<int> container;
    // ...
};

// 变量模板（C++14）
// C++14引入了变量模板，允许创建参数化的变量：
template <typename T>
constexpr T pi = T(3.1415926535897932385);

// 使用
double circle_area = pi<double> * radius * radius;

// 参数包（C++11）
// C++11引入了变参模板，允许处理任意数量的模板参数：
template <typename... Types>
class Tuple
{
    // ...
};

// 声明的作用域
// 模板参数在模板声明或定义的作用域内有效，可以在该作用域内使用：
template <typename T>
class Wrapper
{
    T value;

    template <typename U>
    void convert(U u)
    {
        // 这里可以使用T和U
    }
};

// 模板特化声明
// 可以为特定的模板参数组合提供特殊实现：
// 主模板
template <typename T>
class Specialization;

// 特化
template <>
class Specialization<int>
{
    // 针对int类型的特殊实现
};
